package org.truenewx.tnxjee.repo.redis.support;

import java.util.List;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.truenewx.tnxjee.core.util.ClassUtil;
import org.truenewx.tnxjee.repo.cache.CacheRepo;

/**
 * Redis缓存仓库支持
 *
 * @param <V> 值类型
 * @author jianglei
 */
public abstract class RedisCacheRepoSupport<V, K> implements CacheRepo<V, K>, InitializingBean {

    @Autowired
    protected RedisConnectionFactory connectionFactory;
    private RedisValueTemplate<K, V> accessTemplate;

    @Override
    public void afterPropertiesSet() {
        this.accessTemplate = new RedisValueTemplate<>(this.connectionFactory, getKeyClass(), getValueClass(),
                this::getKeyPrefix);
    }

    protected final RedisValueTemplate<K, V> getAccessTemplate() {
        return this.accessTemplate;
    }

    protected Class<V> getValueClass() {
        return ClassUtil.getActualGenericType(getClass(), 0);
    }

    protected Class<K> getKeyClass() {
        return ClassUtil.getActualGenericType(getClass(), 1);
    }

    /**
     * 获取缓存关键字前缀，前缀用于在redis中区分实体类型，默认为实体类全名
     *
     * @return 缓存关键字前缀
     */
    protected abstract String getKeyPrefix();

    @Override
    public V delete(K key) {
        return getAccessTemplate().delete(key);
    }

    @Override
    public void deleteAll() {
        getAccessTemplate().deleteAll();
    }

    @Override
    public List<V> findAll() {
        return getAccessTemplate().list(value -> true);
    }

    @Override
    public V find(K key) {
        return getAccessTemplate().get(key);
    }

    @Override
    public boolean exists(K key) {
        return getAccessTemplate().hasKey(key);
    }

}
